import { Request, Response } from 'express';
import crypto from 'crypto';

interface TokenRequest {
  uid?: string | null;
  limit?: number | null;
  timeOfHours?: number | null; // 添加timeOfHours参数
}

// 配置的 API Key
const VALID_API_KEY = process.env.DOCMEE_API_KEY || 'ak_s41kObF3rTp5TEAvtT';

// 存储 token 信息
const tokenStore = new Map<string, {
  uid: string | null;
  limit: number | null;
  expireTime: number;
}>();

// 自动从 API Key 生成 token
const generateTokenFromApiKey = () => {
  // 生成新的 token，格式为 sk_随机字符串
  const token = `sk_${crypto.randomBytes(16).toString('hex')}`;
  const expireTime = 7200; // 2小时

  // 存储 token 信息
  tokenStore.set(token, {
    uid: null,
    limit: null,
    expireTime: Date.now() + expireTime * 1000
  });

  console.log('生成新 token:', token);
  return token;
};

// 初始化时生成一个 token
let currentToken = generateTokenFromApiKey();

// 定期检查并更新 token
setInterval(() => {
  const tokenInfo = tokenStore.get(currentToken);
  if (!tokenInfo || Date.now() > tokenInfo.expireTime) {
    currentToken = generateTokenFromApiKey();
  }
}, 60000); // 每分钟检查一次

export const createApiToken = async (req: Request, res: Response) => {
  try {
    const { uid, limit, timeOfHours }: TokenRequest = req.body;
    const apiKey = req.headers['api-key'];

    // 验证 API Key
    if (!apiKey || apiKey !== VALID_API_KEY) {
      return res.status(401).json({
        code: 401,
        message: 'API Key 无效或未提供'
      });
    }

    // 处理过期时间参数（默认2小时，最大48小时）
    const hours = timeOfHours ?? 2;
    const validHours = Math.min(Math.max(hours, 0), 48);
    const expireTimeInSeconds = validHours * 3600;

    // 生成新的 token，格式为 sk_随机字符串
    const token = `sk_${crypto.randomBytes(16).toString('hex')}`;

    // 存储 token 信息
    tokenStore.set(token, {
      uid: uid ?? null,
      limit: limit ?? null,
      expireTime: Date.now() + expireTimeInSeconds * 1000
    });

    // 如果提供了 uid，使之前的 token 在10秒后过期
    if (uid) {
      setTimeout(() => {
        for (const [oldToken, info] of tokenStore.entries()) {
          if (info.uid === uid && oldToken !== token) {
            tokenStore.delete(oldToken);
            console.log(`uid ${uid} 的旧 token 已过期: ${oldToken}`);
          }
        }
      }, 10000); // 10秒后执行
    }

    console.log('生成新 token:', token, '用户 uid:', uid, '限制次数:', limit);

    return res.json({
      code: 0,
      message: '操作成功',
      data: {
        token,
        expireTime: expireTimeInSeconds
      }
    });
  } catch (error) {
    console.error('创建 token 失败:', error);
    return res.status(500).json({
      code: 500,
      message: error instanceof Error ? error.message : '创建 token 失败'
    });
  }
};

// 验证 token 中间件
export const verifyToken = (req: Request, res: Response, next: Function) => {
  try {
    const token = req.headers['token'] as string;
    const apiKey = req.headers['api-key'] as string;

    // 如果提供了 API Key，直接通过
    if (apiKey === VALID_API_KEY) {
      return next();
    }

    // 验证 token
    if (!token) {
      return res.status(401).json({
        code: 401,
        message: '未提供 token'
      });
    }

    const tokenInfo = tokenStore.get(token);
    if (!tokenInfo) {
      return res.status(401).json({
        code: 401,
        message: 'token 无效'
      });
    }

    // 检查是否过期
    if (Date.now() > tokenInfo.expireTime) {
      tokenStore.delete(token);
      return res.status(401).json({
        code: 401,
        message: 'token 已过期'
      });
    }

    // 检查是否是生成 PPT 相关的接口
    const isPptGenerationEndpoint = req.path.includes('/ppt/');
    
    // 检查使用次数限制（仅对 PPT 生成接口生效）
    if (isPptGenerationEndpoint && tokenInfo.limit !== null && tokenInfo.limit <= 0) {
      return res.status(403).json({
        code: 403,
        message: '已达到 PPT 生成次数限制'
      });
    }

    // 更新使用次数（仅对 PPT 生成接口生效）
    if (isPptGenerationEndpoint && tokenInfo.limit !== null) {
      tokenInfo.limit--;
      tokenStore.set(token, tokenInfo);
      console.log(`token ${token} 剩余使用次数: ${tokenInfo.limit}`);
    }

    return next();
  } catch (error) {
    console.error('验证 token 失败:', error);
    return res.status(500).json({
      code: 500,
      message: error instanceof Error ? error.message : '验证 token 失败'
    });
  }
};

// 获取当前 token
export const getCurrentToken = () => currentToken;
